package com.huawang.mdesign.model.service.inter;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.huawang.business.constants.ErrorCode;
import com.huawang.business.constants.ProjectDataTypeEnum;
import com.huawang.business.data.state.ISaveStateService;
import com.huawang.business.dto.ModelPropertyInfo;
import com.huawang.business.dto.ProjectDTO;
import com.huawang.business.dto.graph.ModelInfo;
import com.huawang.business.dto.project.ModelDependency;
import com.huawang.business.dto.project.Project;
import com.huawang.business.dto.project.ProjectConfig;
import com.huawang.business.exception.AbortExecutionException;
import com.huawang.business.service.cowork.ICoworkService;
import com.huawang.business.service.init.IInitializeService;
import com.huawang.business.service.model.base.Cache.NamingRuleCache;
import com.huawang.business.service.model.base.ElementFindService;
import com.huawang.business.service.model.base.UmlService;
import com.huawang.business.service.model.core.InternalUmlService;
import com.huawang.business.service.model.core.ModelPropertyInfoService;
import com.huawang.business.service.model.core.delete.DeleteService;
import com.huawang.business.service.model.core.display.KeywordsCache;
import com.huawang.business.service.model.core.number.GlobalNumberCache;
import com.huawang.business.service.model.core.project.InternalProjectService;
import com.huawang.business.service.model.core.project.ProjectManager;
import com.huawang.business.service.transaction.TransactionServiceImpl;
import com.huawang.business.util.InstanceVoUtils;
import com.huawang.business.util.ValidateDataUtil;
import com.huawang.business.vo.ModelResultVo;
import com.huawang.core.definition.mof.UMLDefinitionConstants;
import com.huawang.core.definition.mof.instances.MetaClassInstance;
import com.huawang.core.definition.mof.util.SnowflakeIdWorkerUtil;
import com.huawang.core.semantics.constants.ModelCreatorType;
import com.huawang.core.semantics.entity.queryResult.MofResultContainer;
import com.huawang.core.semantics.entity.queryResult.QueryPropertyForm;
import com.huawang.core.semantics.entity.transaction.LocalTransaction;
import com.huawang.core.semantics.exception.LocalTransactionNotStartException;
import com.huawang.core.semantics.exception.TransactionNotExistingException;
import com.huawang.mdesign.model.service.constant.ProjectSpecificationEnum;
import com.huawang.mdesign.model.service.dto.DeleteProfileDTO;
import com.huawang.mdesign.model.service.dto.ProjectOpenDTO;
import com.huawang.mdesign.model.service.util.LogUtil;
import com.huawang.mdesign.model.service.util.ReadMd3Utils;
import com.huawang.mdesign.model.service.util.uaf.ProjectUtils;
import com.huawang.mdesign.model.service.vo.KeywordPropertyVO;
import com.huawang.mdesign.model.service.vo.ProfileApplicationVo;
import com.huawang.mdesign.model.service.vo.ProjectVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static com.huawang.business.constants.ModelActionName.ADD_MODEL;
import static com.huawang.business.constants.ModelActionName.DELETE_MODEL;
import static com.huawang.business.constants.ProfileConstants.DEFAULT_PROFILE;

@Service
@Primary
@Slf4j
public class ProfileService {

    @Autowired
    private UmlService umlService;

    @Autowired
    private ProjectManager projectManager;

    @Autowired
    private InternalProjectService internalProjectService;

    @Autowired
    private ISaveStateService iSaveStateService;

    @Autowired
    private InternalUmlService internalUmlService;

    @Autowired
    private ProjectService projectService;

    @Autowired
    private ModelPropertyInfoService modelPropertyInfoService;

    @Autowired
    private TransactionServiceImpl transactionService;

    @Autowired
    private DeleteService deleteService;

    @Autowired
    private ICoworkService coworkService;

    @Autowired
    private IInitializeService initializeService;

    @Autowired
    private ElementFindService elementFindService;

    @Autowired
    private GlobalNumberCache globalNumberCache;

    @Autowired
    private NamingRuleCache namingRuleCache;

    @NotNull
    public ModelResultVo delete(@NotNull final DeleteProfileDTO dto) {
        LogUtil.printSerializeOnlineLogs("dto: ", dto);
        final String projectId = dto.getProjectId();
        final ModelResultVo modelResultVo = new ModelResultVo();
        final Project project = projectManager.getProject(projectId);
        if (project == null) {
            throw AbortExecutionException.build(ErrorCode.PROJECT_NOT_FOUND);
        }

        final String profileName;
        final LocalTransaction transaction = transactionService.createTransaction(projectId, ADD_MODEL);
        try {
            // 移除的profile从缓存项目的dependencies中移除
            final MetaClassInstance profile = internalUmlService.fetchInstance(dto.getProfileId(), projectId);
            if (Objects.nonNull(profile)) {
                profileName = internalUmlService.queryStringProperty(projectId, profile, UMLDefinitionConstants.NamedElement_name);
            } else {
                profileName = null;
            }

            internalProjectService.setGlobalWriteableState(project.getId(), true);
            deleteService.deleteModel(projectId, dto.getProfileId());
            internalUmlService.removeProfileConfig(projectId, dto.getProfileId());
            transactionService.commit(projectId);
            InstanceVoUtils.fillModelResultVo(modelResultVo, transaction);
        } catch (TransactionNotExistingException | LocalTransactionNotStartException e) {
            throw AbortExecutionException.build(ErrorCode.TRANSACTION_ERROR, e);
        } catch (Exception e) {
            transactionService.rollBack(projectId, transaction);
            throw AbortExecutionException.build(ErrorCode.SERVICE_ERROR, e);
        } finally {
            internalProjectService.setGlobalWriteableState(project.getId(), false);
        }

        if (StringUtils.isNotEmpty(profileName)) {
            project.getDependencies().removeIf(it -> it.getProfileName().equals(profileName));
        }
        return modelResultVo;
    }

    @Nullable
    public Project profileEdit(@NotNull final ProjectOpenDTO md3pDto) {
        LogUtil.printSerializeOnlineLogs("md3pDto: ", md3pDto);
        final ProjectDTO projectDto = projectService.makeProjectDto(md3pDto);
        if (!ProjectDataTypeEnum.DB.value().equals(projectDto.getDataType())) {
            return projectService.openByJson(projectDto);
        }
        // 打开的时候db连接存在未关闭的情况，需要删掉再打开
        projectService.delete(projectDto.getProjectId(), md3pDto.getSaveWay());
        return openProfileByDb(projectDto);
    }

    @Nullable
    public Project openProfileByDb(@NotNull final ProjectDTO projectDto) {
        LogUtil.printSerializeOnlineLogs("projectDto: ", projectDto);
        final String projectId = projectDto.getProjectId();
        final String rootId = projectDto.getRootModel();
        ValidateDataUtil.isNotNull(rootId);
        String currentId = SnowflakeIdWorkerUtil.getId();
        projectManager.extractDb(projectDto.getFilePath(), currentId + "_" + projectId, projectDto.getDefaultSaveDir());
        Project project = projectManager.createAndActive(projectId, projectDto.getDependencies(), currentId,
                projectDto.getDefaultSaveDir(), projectDto.getProjectVersion(), ProjectUtils.getProjectSpecificationByProjectDTO(projectDto));
        project.setExport(false);
        List<String> oldDefaultProfile = new ArrayList<>(DEFAULT_PROFILE);
        try {
            ProjectUtils.updateProfileByProjectSpecification(project.getProjectSpecification());
            projectService.loadPrivateData(projectId, project.getProjectSpecification());
            final List<ModelDependency> initProfile = DEFAULT_PROFILE.stream().map(it ->
                    new ModelDependency(it, 1L)).collect(Collectors.toList());
            this.internalProjectService.setGlobalWriteableState(projectId, true);
            MetaClassInstance profile = internalUmlService.fetchExistInstance(projectDto.getRootModel(), projectId);
            List<String> childrenIds = elementFindService.getChildrenCascadeIds(projectId, profile, true);
            internalUmlService.updateProfileModelCreatorType(projectId, childrenIds, ModelCreatorType.CREATE_INTERACTIVE);
            Set<String> profileIds = projectService.initProfileDependency(projectDto.getDependencies(),
                    projectDto.getProfileLibPath(), initProfile, projectDto.getProfileLibPath(), project);
            profileIds.addAll(initProfile.stream().map(ModelDependency::getProfileName).collect(Collectors.toList()));
            profileIds.add(rootId);

            // 重新加载缓存
            this.initializeService.initialize(projectId, false, true, true, project.getProjectSpecification());
            // 创建根节点
            MetaClassInstance rootModel = projectService.createRootModel(project);
            project.setRootModel(rootModel.getId());
            // 设置profile的owner为根节点
            internalProjectService.setProfileOwner(project, rootModel, profileIds);
            if (internalProjectService.isOpenVar(project)) {
                this.iSaveStateService.setIsLoggingVariation(projectId, true);
            }
            if (project.isOnline()) {
                this.iSaveStateService.setIsCoWork(projectId, true);
                coworkService.updateAllPackageIsReadOnlyOrNot(projectId, true);
            }
        } catch (Exception e) {
            ProjectUtils.rollBackDefaultProfile(oldDefaultProfile);
            projectManager.clear(projectId, projectDto.getSaveWay());
            throw AbortExecutionException.build(ErrorCode.PROJECT_OPEN_ERROR, e);
        }
        this.internalProjectService.setGlobalWriteableState(projectId, false);
        return project;
    }

    @NotNull
    public ProfileApplicationVo profileApplicationToCurrentProject(@NotNull final String projectId,
                                                                   @NotNull final String profilePath) {
        LogUtil.printOnlineLogs("projectId: {}, profilePath: {}", projectId, profilePath);
        final Project project = projectManager.getProject(projectId);
        if (Objects.isNull(project)) {
            throw AbortExecutionException.build(ErrorCode.PROJECT_NOT_FOUND);
        }
        ReadMd3Utils.MD3FileInfo md3pInfo = ReadMd3Utils.unZip(profilePath);
        final String projectData = md3pInfo.readMofProject();
        if (StringUtils.isEmpty(projectData)) {
            throw AbortExecutionException.build(ErrorCode.PROJECT_DATA_READ_ERROR);
        }
        ProfileApplicationVo profileApplicationVo = new ProfileApplicationVo();
        ModelResultVo modelResultVo = new ModelResultVo();

        LocalTransaction transaction = transactionService.createTransaction(projectId, ADD_MODEL);
        try {
            final ProjectVo projectVo = new ObjectMapper().readValue(projectData, ProjectVo.class);
            String profileInstanceId = projectVo.getRootModel();

            // 改变当前项目中profile模型层级结构
            Map<String, MetaClassInstance> metaClassInstanceMap = internalUmlService.fetchInstances(Stream.of(project.getRootModel(),
                    profileInstanceId).collect(Collectors.toList()), projectId);
            MetaClassInstance model = metaClassInstanceMap.get(project.getRootModel());
            MetaClassInstance profile = metaClassInstanceMap.get(profileInstanceId);
            umlService.updateModel(projectId, profileInstanceId, UMLDefinitionConstants.Element_owner, model);

            // 使profile在当前项目生效且标记为导入的profile
            List<String> childrenIds = elementFindService.getChildrenCascadeIds(projectId, profile, true);
            internalUmlService.setIsReadOnly(projectId, childrenIds);
            internalUmlService.updateProfileModelCreatorType(projectId, childrenIds, ModelCreatorType.IMPORT_FROM_PROFILE);
            internalUmlService.updateProfileMetaClass(projectId, profileInstanceId, false, true, true, true);
            transactionService.commit(projectId);
            InstanceVoUtils.fillModelResultVo(modelResultVo, transaction);
        } catch (TransactionNotExistingException | LocalTransactionNotStartException e) {
            throw AbortExecutionException.build(ErrorCode.TRANSACTION_ERROR, e);
        } catch (IOException e) {
            throw AbortExecutionException.build(ErrorCode.JSON_DATA_PARSE_ERROR, e);
        }
        final ProjectConfig config = md3pInfo.readConfig();
        final List<ModelDependency> dependencies = project.getDependencies();
        if (Objects.nonNull(config) && Objects.nonNull(config.getProfileName()) && Objects.nonNull(config.getProfileVersion())) {
            deleteService.deleteModel(projectId, project.getId());
            if (dependencies.stream().anyMatch(it -> StringUtils.equals(it.getProfileName(), config.getProfileName()))) {
                throw AbortExecutionException.build(ErrorCode.PROFILE_IS_IMPORTED);
            }
            dependencies.add(new ModelDependency(config.getProfileName(), config.getProfileVersion()));
        }
        profileApplicationVo.setModelDependencies(dependencies);
        profileApplicationVo.setModelResultVo(modelResultVo);

        return profileApplicationVo;
    }

    @NotNull
    public ProfileApplicationVo addProfileInCurrentProject(@NotNull final String projectId,
                                                           @NotNull final String profilePath,
                                                           @NotNull final String profileLibPath,
                                                           final String onlineProfileLibPath,
                                                           final boolean isProfileProject) {
        LogUtil.printOnlineLogs("projectId: {}, profilePath: {}, profileLibPath: {}, onlineProfileLibPath: {}, isProfileProject: {}",
                projectId, profilePath, profileLibPath, onlineProfileLibPath, isProfileProject);
        final Project project = projectManager.getProject(projectId);
        if (Objects.isNull(project)) {
            throw AbortExecutionException.build(ErrorCode.PROJECT_NOT_FOUND);
        }
        ReadMd3Utils.MD3FileInfo md3pInfo = ReadMd3Utils.unZip(profilePath);
        final String projectData = md3pInfo.readMofProject();
        if (StringUtils.isEmpty(projectData)) {
            throw AbortExecutionException.build(ErrorCode.PROJECT_DATA_READ_ERROR);
        }

        final List<ModelDependency> initProfile = DEFAULT_PROFILE.stream().map(it ->
                new ModelDependency(it, 1L)).collect(Collectors.toList());
        final ProjectConfig config = md3pInfo.readConfig();
        final List<ModelDependency> dependencies = new ArrayList<>(project.getDependencies());
        ModelDependency newDependency = null;
        if (Objects.nonNull(config) && Objects.nonNull(config.getProfileName()) && Objects.nonNull(
                config.getProfileVersion())) {
            if (dependencies.stream().anyMatch(
                    it -> StringUtils.equals(it.getProfileName(), config.getProfileName()))) {
                throw AbortExecutionException.build(ErrorCode.PROFILE_IS_IMPORTED);
            }

            newDependency = new ModelDependency(config.getProfileName(), config.getProfileVersion());
            dependencies.add(newDependency);
        }
        ProfileApplicationVo profileApplicationVo = new ProfileApplicationVo();
        ModelResultVo modelResultVo = new ModelResultVo();
        LocalTransaction transaction = transactionService.createTransaction(projectId, ADD_MODEL);
        try {
            final ProjectVo projectVo = new ObjectMapper().readValue(projectData, ProjectVo.class);
            String profileInstanceId = projectVo.getRootModel();
            Set<String> importProfiles;
            if (isProfileProject) {
                importProfiles = projectService.initProfileDependency(dependencies, profileLibPath, initProfile, profileLibPath, project);
            } else {
                if (project.isOnline()) {
                    importProfiles =   projectService.initProfileDependency(dependencies,
                            onlineProfileLibPath,
                            initProfile, profileLibPath, project);
                } else {
                    importProfiles = projectService.initProfileDependency(dependencies,
                            profileLibPath,
                            initProfile, profileLibPath, project);
                }

            }
            internalProjectService.setGlobalWriteableState(project.getId(), true);
            // 改变当前项目中profile模型层级结构
            Set<String> updateProfiles = Stream.concat(importProfiles.stream(), Stream.of(profileInstanceId)).collect(Collectors.toSet());
            MetaClassInstance model = internalUmlService.fetchInstance(project.getRootModel(), projectId);
            internalProjectService.setProfileOwner(project, model, updateProfiles);

            updateProfiles.forEach(it ->
                    internalUmlService.updateProfileMetaClass(projectId, it, false, true, true, true));

            transactionService.commit(projectId);
            InstanceVoUtils.fillModelResultVo(modelResultVo, transaction);
        } catch (TransactionNotExistingException | LocalTransactionNotStartException e) {
            throw AbortExecutionException.build(ErrorCode.TRANSACTION_ERROR, e);
        } catch (IOException e) {
            transactionService.rollBack(projectId, transaction);
            throw AbortExecutionException.build(ErrorCode.JSON_DATA_PARSE_ERROR, e);
        } catch (Exception e) {
            log.error("导入profile失败", e);
            transactionService.rollBack(projectId, transaction);
            throw AbortExecutionException.build(ErrorCode.PROFILE_IMPORT_ERROR, e);
        } finally {
            internalProjectService.setGlobalWriteableState(project.getId(), false);
        }

        profileApplicationVo.setModelDependencies(project.getDependencies());
        profileApplicationVo.setModelResultVo(modelResultVo);
        if (newDependency != null) {
            projectManager.addDependency(project, newDependency);
        }

        return profileApplicationVo;

    }

    @NotNull
    public ModelResultVo removeProfileInCurrentProject(@NotNull final DeleteProfileDTO deleteProfileDto) {
        LogUtil.printSerializeOnlineLogs("deleteProfileDto: {}", deleteProfileDto);
        final String projectId = deleteProfileDto.getProjectId();
        final ModelResultVo modelResultVo = new ModelResultVo();
        Project project = projectManager.getProject(projectId);
        if (project == null) {
            throw AbortExecutionException.build(ErrorCode.PROJECT_NOT_FOUND);
        }

        final LocalTransaction transaction = transactionService.createTransaction(projectId, DELETE_MODEL);
        try {
            // 移除的profile从缓存项目的dependencies中移除
            MetaClassInstance profile = internalUmlService.fetchInstance(deleteProfileDto.getProfileId(), projectId);
            if (Objects.nonNull(profile)) {
                String profileName = internalUmlService.queryStringProperty(projectId, profile, UMLDefinitionConstants.NamedElement_name);
                List<ModelDependency> dependencies = project.getDependencies();
                dependencies.removeIf(it -> StringUtils.equals(it.getProfileName(), profileName));
                project.setDependencies(dependencies);
            }
            internalProjectService.setGlobalWriteableState(project.getId(), true);
            internalUmlService.updateProfileInvalid(projectId, deleteProfileDto.getProfileId(), true);
            deleteService.deleteModel(projectId, deleteProfileDto.getProfileId());
            internalUmlService.removeProfileConfig(projectId, deleteProfileDto.getProfileId());
            transactionService.commit(projectId);
            InstanceVoUtils.fillModelResultVo(modelResultVo, transaction);
        } catch (TransactionNotExistingException | LocalTransactionNotStartException e) {
            throw AbortExecutionException.build(ErrorCode.TRANSACTION_ERROR, e);
        } catch (Exception e) {
            transactionService.rollBack(projectId, transaction);
            throw AbortExecutionException.build(ErrorCode.SERVICE_ERROR, e);
        } finally {
            internalProjectService.setGlobalWriteableState(project.getId(), false);
        }

        return modelResultVo;
    }

    public void loadPrivateData(@NotNull final String projectId) {
        LogUtil.printOnlineLogs("loadPrivateData -> projectId: ", projectId);
        this.initializeService.initialize(projectId, false, true, true, ProjectSpecificationEnum.SYSMML.value());
        // 清除全局编号配置缓存
        globalNumberCache.removeNumberPropertyWithAutoNumbersMap(projectId);
        globalNumberCache.putNumberProperties(projectId);
        // 清除命名规则缓存
        namingRuleCache.removeNamingRuleMap(projectId);
        namingRuleCache.putNamingRuleMap(projectId);
    }

    @NotNull
    public List<KeywordPropertyVO> queryKeywordProperty(@NotNull final String projectId) {
        LogUtil.printOnlineLogs("queryKeywordProperty -> projectId: ", projectId);
        final Map<String, String> stereotypeKeywordsMap = getStereotypeKeywordsMap(projectId);

        //重新加载keywords缓存
        KeywordsCache.putKeywordsMap(projectId, stereotypeKeywordsMap);

        List<MetaClassInstance> models =
                internalUmlService.querySpecifiedInstanceList(projectId, stereotypeKeywordsMap.keySet());

        List<ModelPropertyInfo> modelInfoList = modelPropertyInfoService.createModelPropertyInfoList(projectId, models,
                Stream.of(UMLDefinitionConstants.Element_appliedStereotype).collect(Collectors.toList()));

        Map<String, String> stereotypeCnNameMap = new HashMap<>();
        List<MetaClassInstance> batchStereotypes = new ArrayList<>();
        List<MetaClassInstance> modelInstances = modelInfoList.stream().map(ModelPropertyInfo::getInstance).collect(Collectors.toList());
        QueryPropertyForm queryPropertyForm = internalUmlService.getQueryPropertyForm(modelInstances, UMLDefinitionConstants.Element_appliedStereotype);
        MofResultContainer mofResultContainer = this.internalUmlService.queryProperty(projectId, queryPropertyForm);
        modelInfoList.stream()
                .flatMap(modelInfo ->
                        mofResultContainer.queryListInstanceProperty(modelInfo.getInstanceId(),
                                        UMLDefinitionConstants.Element_appliedStereotype).stream()
                                .filter(it -> !ModelService.isHideProperty(it.getId())))
                .forEach(stereotype -> {
                    ModelInfo info = internalUmlService.fetchStereotypeModelInfo(stereotype.getId());
                    if (Objects.nonNull(info)) {
                        stereotypeCnNameMap.put(stereotype.getId(), info.getCnName());
                    } else {
                        batchStereotypes.add(stereotype);
                    }
                });
        List<ModelPropertyInfo> stereotypeNameList = modelPropertyInfoService.createModelPropertyInfoList(projectId,
                batchStereotypes, Stream.of(UMLDefinitionConstants.NamedElement_name).collect(Collectors.toList()));
        stereotypeNameList.forEach(it -> stereotypeCnNameMap.put(it.getInstanceId(), it.queryStringValue(UMLDefinitionConstants.NamedElement_name)));

        List<KeywordPropertyVO> voList = new ArrayList<>();
        modelInfoList.forEach(modelInfo -> {
            KeywordPropertyVO vo = new KeywordPropertyVO();
            vo.setModelId(modelInfo.getInstanceId());
            List<String> keywords = new ArrayList<>();
            List<MetaClassInstance> stereotypes = modelInfo.queryListInstanceValue(UMLDefinitionConstants.Element_appliedStereotype);
            stereotypes.forEach(stereotype -> {
                final String stereotypeId = stereotype.getId();
                if (!stereotypeKeywordsMap.containsKey(stereotypeId) && !stereotypeCnNameMap.containsKey(stereotypeId)) {
                    return;
                }
                if (stereotypeKeywordsMap.containsKey(stereotypeId)) {
                    keywords.add(stereotypeKeywordsMap.get(stereotypeId));
                } else {
                    keywords.add(stereotypeCnNameMap.get(stereotypeId));
                }
            });
            vo.setKeywords(keywords);
            voList.add(vo);
        });

        return voList;
    }

    @NotNull
    public Map<String, String> getStereotypeKeywordsMap(String projectId) {
        LogUtil.printOnlineLogs("getStereotypeKeywordsMap -> projectId: ", projectId);
        List<MetaClassInstance> customizationList = internalUmlService.querySpecifiedInstanceList(projectId,
                UMLDefinitionConstants.Customization_Customization);

        List<ModelPropertyInfo> modelPropertyInfoList = modelPropertyInfoService.createModelPropertyInfoList(projectId, customizationList,
                Stream.of(UMLDefinitionConstants.Customization_Customization_keyword,
                        UMLDefinitionConstants.Customization_Customization_customizationTarget).collect(Collectors.toList()));
        Map<String, String> modelKeywordsMap = new HashMap<>();
        List<MetaClassInstance> modelInstances = modelPropertyInfoList.stream()
                .map(ModelPropertyInfo::getInstance).collect(Collectors.toList());
        QueryPropertyForm queryPropertyForm = this.internalUmlService.getQueryPropertyForm(modelInstances,
                Stream.of(UMLDefinitionConstants.Customization_Customization_keyword,
                        UMLDefinitionConstants.Customization_Customization_customizationTarget).collect(Collectors.toList()));
        MofResultContainer mofResultContainer = this.internalUmlService.queryProperty(projectId, queryPropertyForm);
        modelPropertyInfoList.forEach(info -> {
            String keyword = mofResultContainer.queryStringProperty(info.getInstanceId(),
                    UMLDefinitionConstants.Customization_Customization_keyword);
            List<MetaClassInstance> targetList =
                    mofResultContainer.queryListInstanceProperty(info.getInstanceId(),
                            UMLDefinitionConstants.Customization_Customization_customizationTarget);
            if (StringUtils.isBlank(keyword) || CollectionUtils.isEmpty(targetList)) {
                return;
            }
            targetList.forEach(target -> modelKeywordsMap.putIfAbsent(target.getId(), keyword));
        });
        return modelKeywordsMap;
    }
}
